package cqrtplm.service.impl;

import com.ty.basic.entity.org.UserDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.dto.RTCertFiledFormDTO;
import cqrtplm.entity.RtCertFiledCustomerDO;
import cqrtplm.entity.RtCertFiledPartManufacturDO;
import cqrtplm.entity.RtCertFiledPartinfoDO;
import cqrtplm.mapper.RtCertFiledPartManufacturMapper;
import cqrtplm.mapper.RtCertFiledPartinfoMapper;
import cqrtplm.service.RtCertFiledPartManufacturService;
import cqrtplm.service.RtCertFiledPartinfoService;
import cqrtplm.util.RTLogHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 零部件信息服务实现
 */
@Service
@Slf4j
public class RtCertFiledPartinfoServiceImpl implements RtCertFiledPartinfoService {

    @Resource
    private RtCertFiledPartinfoMapper rtCertFiledPartinfoMapper;
    @Resource
    private RtCertFiledPartManufacturMapper rtCertFiledPartManufacturMapper;
@Resource
private RtCertFiledPartManufacturService rtCertFiledPartManufacturService;

    @Resource
    private RTLogDifferenceServiceImpl rtLogDifferenceService;

    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;

    @Resource
    private RTLogHelper rtLogHelper;

    @Override
    public RtCertFiledPartinfoDO selectRtCertFiledPartinfoById(String id) {
        RtCertFiledPartinfoDO item = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoById(id);
        List<RtCertFiledPartManufacturDO> mlist=rtCertFiledPartManufacturMapper.selectRtCertFiledPartManufacturByPartId(id);
        if(mlist != null && !mlist.isEmpty())
            item.setManufacturerlist(mlist);

        return item;
    }

    @Override
    public List<RtCertFiledPartinfoDO> selectRtCertFiledPartinfoList(RtCertFiledPartinfoDO rtCertFiledPartinfo) {
        List<RtCertFiledPartinfoDO> list = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoList(rtCertFiledPartinfo);
        return list;
    }

    @Override
    public List<RtCertFiledPartinfoDO> selectRtCertFiledPartinfoListWithManufactorList(
            RtCertFiledPartinfoDO rtCertFiledPartinfo) {
        List<RtCertFiledPartinfoDO> list = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoList(rtCertFiledPartinfo);
        List<RtCertFiledPartManufacturDO> mlist=rtCertFiledPartManufacturMapper.selectRtCertFiledPartManufacturByFiledId(rtCertFiledPartinfo.getFiledId());

        if(mlist != null && !mlist.isEmpty()) {
            Map<String, List<RtCertFiledPartManufacturDO>> manufacturerMap = mlist.stream()
                    .filter(m -> m.getPartId() != null)
                    .collect(Collectors.groupingBy(RtCertFiledPartManufacturDO::getPartId));

            list.forEach(item -> {
                item.setManufacturerlist(manufacturerMap.getOrDefault(item.getId(), Collections.emptyList()));
            });
        }
        return list;
    }

    @Override
    public String insertRtCertFiledPartinfo(RtCertFiledPartinfoDO rtCertFiledPartinfo) {

        List<RtCertFiledPartinfoDO> old = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoByDO(rtCertFiledPartinfo);
        if(old != null && !old.isEmpty()) {
            throw RTErrorCodeEnum.DATA_EXISTS.getException("该件号已存在，请勿重复添加");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            String snowId = String.valueOf(snowflakeIdComponent.getInstance().nextId());
            Timestamp timestamp = new Timestamp(new Date().getTime());
            if(rtCertFiledPartinfo.getId() == null || rtCertFiledPartinfo.getId().isEmpty())
                rtCertFiledPartinfo.setId(snowId);
            rtCertFiledPartinfo.setPartNo(rtCertFiledPartinfo.getPartNo().toUpperCase());
            rtCertFiledPartinfo.setCreateTime(timestamp);
            rtCertFiledPartinfo.setCreateUserId(String.valueOf(user.getOid()));
            rtCertFiledPartinfo.setCreateUserName(user.getName());
            if(rtCertFiledPartinfo.getIsEnabled() == null || rtCertFiledPartinfo.getIsEnabled().isEmpty())
                rtCertFiledPartinfo.setIsEnabled("1");

            log.info("零部件信息-新增{},{},{},{}",
                     rtCertFiledPartinfo.getPartNo(),
                     snowId,
                     timestamp,
                     user.getName());

             rtCertFiledPartinfoMapper.insertRtCertFiledPartinfo(rtCertFiledPartinfo);

             //零部件供应商
             if(rtCertFiledPartinfo.getManufacturerlist()!=null && !rtCertFiledPartinfo.getManufacturerlist().isEmpty()) {
                 rtCertFiledPartinfo.getManufacturerlist().forEach(
                         item -> {
                             item.setFiledId(rtCertFiledPartinfo.getFiledId());
                             item.setPartId(rtCertFiledPartinfo.getId());
                             item.setPartCode(null);
                             rtCertFiledPartManufacturService.insertRtCertFiledPartManufactur(item);
                         }
                 );
             }
            return snowId;
        }
    }

    @Override
    @Transactional
    public int updateRtCertFiledPartinfo(RtCertFiledPartinfoDO rtCertFiledPartinfo,RTCertFiledFormDTO formDTO) {
        RtCertFiledPartinfoDO old = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoById(rtCertFiledPartinfo.getId());
        if(old == null) {
            throw RTErrorCodeEnum.DATA_NOT_EXISTS.getException("该备案零部件不存在，请检查");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            Timestamp timestamp = new Timestamp(new Date().getTime());
            rtCertFiledPartinfo.setUpdateTime(timestamp);
            rtCertFiledPartinfo.setUpdateUserId(String.valueOf(user.getOid()));
            rtCertFiledPartinfo.setUpdateUserName(user.getName());

            int r = rtCertFiledPartinfoMapper.updateRtCertFiledPartinfo(rtCertFiledPartinfo);
            if(r > 0) {
                // 记录差异日志
                rtLogDifferenceService.newLog(
                        rtCertFiledPartinfo, old,
                        rtCertFiledPartinfo.getId(),
                        rtCertFiledPartinfo.getCreateUserName(),
                        "零部件信息",
                        "修改",
                        ""
                );
            }

            //零部件供应商

            if(formDTO==null){
                formDTO = new RTCertFiledFormDTO();
                formDTO.setId(rtCertFiledPartinfo.getFiledId());
                formDTO.setEditWithoutDelete(false);
            }

            List<RtCertFiledPartManufacturDO>  manufacturerlist = rtCertFiledPartinfo.getManufacturerlist();
            if(manufacturerlist!=null && !manufacturerlist.isEmpty()) {
                  rtCertFiledPartManufacturService.updateEntityList(
                          formDTO,
                        rtCertFiledPartinfo.getId() ,
                        manufacturerlist
                );
            }
            return r;
        }
    }

    @Override
    public void updateEntityList(RTCertFiledFormDTO formDTO, List<RtCertFiledPartinfoDO> list) {
        String filedId = formDTO.getRtCertFiledDO().getId();
        // 获取数据库中现有的客户列表
        if(!list.isEmpty()){
            RtCertFiledPartinfoDO q = new RtCertFiledPartinfoDO();
            q.setFiledId(filedId);
            List<RtCertFiledPartinfoDO> existingList = selectRtCertFiledPartinfoList(q);

            // 获取数据库中所有存在的ID集合
            Set<String> existingIds = existingList.stream()
                    .map(RtCertFiledPartinfoDO::getId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            // 编辑操作进行增量处理

            // 1. 找出需要删除的记录（存在于数据库但不在新列表中）
            List<RtCertFiledPartinfoDO> toDelete = existingList.stream()
                    .filter(existing -> list.stream().noneMatch(newItem -> Objects.equals(newItem.getId(), existing.getId())))
                    .collect(Collectors.toList());

            // 2. 找出需要更新的记录（ID匹配但内容不同）
            List<RtCertFiledPartinfoDO> toUpdate = list.stream()
                    .filter(item -> item.getId() != null && existingIds.contains(item.getId().toString()))
                    .collect(Collectors.toList());

            // 3. 找出需要新增的记录（ID为null或不在数据库中）
            List<RtCertFiledPartinfoDO> toInsert = list.stream()
                    .filter(item -> item.getId() == null || !existingIds.contains(item.getId().toString()))
                    .collect(Collectors.toList());


            // 执行操作
            if (Boolean.FALSE.equals(formDTO.getEditWithoutDelete())) {
                toDelete.forEach(item -> deleteRtCertFiledPartinfoById(item.getId()));
            }
            toUpdate.forEach(item -> {
                item.setFiledId(filedId);
                updateRtCertFiledPartinfo(item,formDTO);
            });

            toInsert.forEach(item -> {
                item.setFiledId(filedId);
                insertRtCertFiledPartinfo(item);
            });
        }
    }

    @Override
    public int deleteRtCertFiledPartinfoByIds(List<String> ids) {
        return rtCertFiledPartinfoMapper.deleteRtCertFiledPartinfoByIds(ids);
    }

    @Override
    public int deleteRtCertFiledPartinfoById(String id) {
        rtCertFiledPartManufacturMapper.deleteRtCertFiledPartManufacturByPartId(id);
        return rtCertFiledPartinfoMapper.deleteRtCertFiledPartinfoById(id);
    }
    @Override
    public int deleteRtCertFiledPartinfoByFiledId(String id) {
        return rtCertFiledPartinfoMapper.deleteRtCertFiledPartinfoByFiledId( id);
    }

  @Override
public RtCertFiledPartinfoDO selectRtCertFiledPartinfoByDO(RtCertFiledPartinfoDO entity) {
    List<RtCertFiledPartinfoDO> list = rtCertFiledPartinfoMapper.selectRtCertFiledPartinfoByDO(entity);
    return list.isEmpty() ? null : list.get(0);
}

    @Override
    public List<String> getPartTypeList() {
        return rtCertFiledPartinfoMapper.getPartTypeList();
    }


}